const crypto = require('crypto');
const Controller = require('egg').Controller;
const nodemailer = require('nodemailer');
const fs = require('fs');
const fsPromises = fs.promises;

const cryPass = pass => {
    return crypto.createHash('sha256').update(pass).digest('hex');
};
/**
 * {des} user ability
 */
class MemberController extends Controller {
    /**
     * {des} user register
     */
    async user_register() {
        const query = this.ctx.request.body,
            // email = query.email,
            username = query.username,
            password = query.password,
            pass = cryPass(password);
        try {
            const isExist = await this.ctx.service.member.member_unique({ username });
            if(isExist) {
                return this.ctx.body = {
                    s: 0,
                    m: '用户已存在',
                    d: {},
                };
            }else {
                await this.ctx.service.member.member_register({username, pass});
                this.ctx.status = 200;
                return this.ctx.body = {
                    s: 1,
                    m: 'ok',
                    d: {},
                }
            }
        } catch(err) {
            return this.ctx.body = {
                s: 0,
                m: `fail~${err}`,
                d: {},
            };
        }
    }
    /**
     * {des} add user
     */
    // async user_add() {
    //     const query = this.ctx.request.body,
    //         username = query.username,
    //         realname = query.realname,
    //         mobile = query.mobile,
    //         email = query.email,
    //         roles = query.roles,
    //         status = query.status,
    //         pass = cryPass('888888'),
    //         remark = query.remark;
    //     try {
    //         const isExist = await this.ctx.service.user.user_username(username);
    //         if(isExist) {
    //             return this.ctx.body = {
    //                 s: 0,
    //                 m: '用户已存在',
    //                 d: {}
    //             };
    //         }else {
    //             await this.ctx.service.user.user_add({username, realname, mobile, email, pass, roles, status, remark});
    //             this.ctx.status = 200;
    //             return this.ctx.body = {
    //                 s: 1,
    //                 m: 'ok',
    //                 d: {},
    //             }
    //         }
    //     } catch(err) {
    //         return this.ctx.body = {
    //             s: 0,
    //             m: `fail~${err}`,
    //             d: {},
    //         };
    //     }
    // }
    /**
     * {des} update user
     */
    async user_update() {
        const query = this.ctx.request.body,
            uId = query.id,
            username = query.username,
            realname = query.realname,
            mobile = query.mobile,
            email = query.email,
            roles = query.roles,
            status = query.status,
            remark = query.remark;
        let obj = {username, realname, mobile, email, roles, status, remark};
        if(query.repass == '1') {
            obj['pass'] = cryPass('888888');
        }
        // if(query.roles == 7) {
        //     obj['menus'] = query.menus;
        // }
        
        try {
            // if(roles) {
            //     const menus = await this.ctx.service.role.role_findById(roles),
            //         permission = [];
            //     menus.menus.map(item => {
            //         if(item.permi) {
            //             permission.push(item.permi);
            //         } 
            //     })
            //     obj['permissions'] = permission;
            // }
            // 更新用户信息
            await this.ctx.service.member.member_update(uId,obj);
            // 查询用户信息
            const user = await this.ctx.service.member.member_findById(uId);
            const uinfo = {
                id: user._id,
                username: user.username,
                realname: user.realname,
                mobile: user.mobile,
                email: user.email,
                avatars: user.avatarsPath,
                // articles: user.articles,
                // collect: user.collect,
                // comments: user.comments,
                roles: user.roles,
                permissions: user.permissions,
                menus: user.menus,
                date: user.date
            };
            this.ctx.session.user = uinfo;

            this.ctx.status = 200;
            return this.ctx.body = {
                s: 1,
                m: `ok`,
                d: {}
            }
        } catch(err) {
            return this.ctx.body = {
                s: 0,
                m: `fail~${err}`,
                d: {}
            };
        }
    }
    /**
     * {des} user login
     */
    async user_login() {
        const query = this.ctx.request.body,
            // email = query.email,
            username = query.username,
            pass = query.password,
            hash = crypto.createHash('sha256'),
            pwd = hash.update(pass).digest('hex');
		try {            
            const user = await this.ctx.service.member.member_unique({ username });
            // console.log('172...', user);
            if(!!user && user.pass === pwd) {
                const uinfo = user;
                this.ctx.session.user = uinfo;
                const token = await this.app.jwt.sign({
                    id: user._id,
                    username: user.username,
                    date: user.date,
                    collect: user.collect
                }, this.app.config.jwt.secret);
                this.ctx.status = 200;
                return this.ctx.body = {
                    s: 1,
                    m: 'ok~',
                    d: { token }
                }
            }else {
                return this.ctx.body = {
                    s: 0,
                    m: 'fail~用户信息不存在或密码错误！',
                    d: {},
                }
            }
		}catch(err) {
			return this.ctx.body = {
				s: 0,
                m: `fail~${err}`,
                d: {},
			}
		}
    }
    /**
     * {des} user list
     */
    async user_list() {
        console.log('206...');
        try {
            const user = await this.ctx.service.member.member_list(),
                uinfo = [];
            user.map(it => {
                uinfo.push({
                    id: it._id,
                    username: it.username,
                    realname: it.realname,
                    mobile: it.mobile,
                    email: it.email,
                    avatars: it.avatarsPath,
                    // articles: it.articles,
                    // collect: it.collect,
                    // comments: it.comments,
                    // roles: it.roles,
                    grade: it.grade,
                    permission: it.permissions,
                    // menus: it.menus,
                    status: it.status,
                    remark: it.remark,
                    date: it.date
                })
            })
            this.ctx.status = 200;
            return this.ctx.body = {
                s: 1,
                m: 'ok',
                d: uinfo
            }
        } catch(err) {
            return this.ctx.body = {
                s: 0,
                m: `fail~${err}`
            }
        }
    }
    /**
     * {des} user info
     */
    async user_info() {
        try {
            const uId = this.ctx.state.user.id;
            // if(uId) {
                const user = await this.ctx.service.member.member_findById(uId);
                const uinfo = {
                    id: user._id,
                    username: user.username,
                    realname: user.realname,
                    mobile: user.mobile,
                    email: user.email,
                    avatars: user.avatarsPath,
                    articles: user.articles,
                    collect: user.collect,
                    comments: user.comments,
                    roles: user.roles,
                    date: user.date
                };
                this.ctx.status = 200;
                return this.ctx.body = {
                    s: 1,
                    m: `ok~`,
                    d: uinfo,
                };

            // }else {
            //     return this.ctx.body = {
            //         s: 0,
            //         m: `fail~用户登录信息失效，请重新登录`,
            //         d: {},
            //     }
            // }
        } catch(err) {
            return this.ctx.body = {
                s: 0,
                m: `fail~${err}`,
                d: {},
            };
        }
    }
    // 发送邮件验证码
	async send_emailCode() {
		const query = this.ctx.request.body;
		const email = query.email, code = this.ctx.helper.getRandomStr(11);
		const transport = nodemailer.createTransport({
		  host: 'smtp.qq.com',
		  port: 465,
		  secure: true,
		  auth: {
		    user: '896011631@qq.com',
		    pass: 'qmywbzbrnckwbbjc'
		  }
		});
		const mailInfo = {
		  from: '"DelBug社区" <896011631@qq.com>',
		  to: email,
		  subject: '来自DelBug社区的注册验证邮件~',
		  html: '<p>'+email+' 您好，欢迎加入DelBug社区!</p>\
		  <p>请在10分钟内复制验证码：\
		  <b style="background-color:#f6f8fa;font-size:22px;font-weight:300px;color:red;">\
		  '+ code +'</b>&nbsp;&nbsp;&nbsp;验证注册.</p>'
		};
		try {
			await transport.sendMail(mailInfo).then(() => {
				this.ctx.status = 200;
				this.ctx.session.emailCode = code;
				return this.ctx.body = {
					s: 1,
					m: 'ok',
					d: {}
				}
			})
		}catch(err) {
			return this.ctx.body = {
				s: 0,
                m: '验证码发送失败~',
                d: {},
			}
		}
	}
	// 验证邮箱验证码
	async identify_emailCode() {
		const query = this.ctx.request.body;
		const code = query.emailCode,
		    emailCode = this.ctx.session.emailCode;
		if(code === emailCode) {
            this.ctx.status = 200;
            return this.ctx.body = {
                s: 1,
                m: 'ok',
                d: {},
            }
		}else {
            return this.ctx.body = {
                s: 0,
                m: 'fail~',
                d: {}
            }
        }
    }
    /** 
     * {des} user logout
     */
    async user_logout() {
        this.ctx.session.user = null;
        const isLogin = null;
        if(!isLogin) {
            return this.ctx.body = {
                s: 1,
                m: 'ok',
                d: {},
            };
        }
    }
    /**
     * {des} update avatars
     * code: 200--成功；101--文件类型不合法；102--文件大小不合法；
     */
	async user_avatars() {
        const createPath = (path) => {
            let nP = '', dP = '', i = 0;
            let dir = path.split('/'), len = dir.length;
            dir.splice(-1, 1);
            nP = dir.join('\\') +'\\';
            dir.splice(0, 1);
            dP = dir.join('/') + '/';
            return [nP, dP];
        };  // 路径转换
        const imgT = ['png', 'jpg', 'jpeg', 'gif'];
        const us = this.ctx.session.user,
            uId = us.id,  // 用户ID
            uNm = us.email;  // 用户昵称/mail前6位,用于拼接头像名
        // console.log('341............', this.ctx.request.file);
        const files = this.ctx.request.file,
            fT = files.mimetype.split('/')[1],  // 文件类型
            fZ = files.size;  // 文件大小
            console.log('367.............', files);
        // 文件类型和大小限制
        if(imgT.includes(fT)) {  // 限制文件类型 ['png', 'jpg', 'jpeg', 'gif']
            if(Math.floor(fZ/1024) <= 1024) {  // 限制大小 1MB
                const newFileName = `${uNm}.${fT}`,  // 新文件名
                    dir = createPath(files.destination),  // 存放目录
                    oldPath = files.path,  // 上传的源文件
                    newPath = dir[0] + newFileName,  // 写入文件库的图片
                    dataPath = dir[1] + newFileName;  // 写入数据库的图片
                try {
                    // 检查是否已有头像 循环检查目录
                    for(let i=0,len=imgT.length; i<len; i++) {
                        const oldAva = `${dir[0] + uNm}.${imgT[i]}`;
                        try {
                            fs.accessSync(oldAva, fs.constants.F_OK);
                            fsPromises.unlink(oldAva);
                        }catch(err) {}
                    }
                    fsPromises.rename(oldPath, newPath);  // 文件重命名
                    // 头像地址更新至数据库
                    
                    const user = await this.ctx.service.member.member_update(uId, {avatarsPath: dataPath});
                    const uinfo = {
                        id: user._id,
                        username: user.username,
                        realname: user.realname,
                        mobile: user.mobile,
                        email: user.email,
                        avatars: user.avatarsPath,
                        articles: user.articles,
                        collect: user.collect,
                        comments: user.comments,
                        roles: user.roles,
                        permission: user.permissions,
                        menus: user.menus,
                        date: user.date
                    };
                    this.ctx.session.user = uinfo;
    
                    this.ctx.status = 200;
                    return this.ctx.body = {
                        s: 1,
                        m: 'ok',
                        d: uinfo
                    }
                }catch(err) {
                    this.ctx.status = 500;
                    return this.ctx.body = {
                        s: 0,
                        m: `Fail~${err}`,
                        d: {}
                    }
                }
            }else {
                return this.ctx.body = {
                    s: 102,
                    m: `Fail~Image大小不合法！`,
                    d: {}
                }
            }
        }else {
            return this.ctx.body = {
                s: 101,
                m: `Fail~Image类型不合法！`,
                d: {}
            }
        }
		
        // const fileStream = await this.ctx.getFileStream(),
        //     fieldName = fileStream.fieldname,
        //     fileName = fileStream.filename;
            
        // // const dir = path.join(this.config.setting.uploadDir);
        // const writeStream = fs.createWriteStream('app/public/uploads');
        // console.log('218*******',fileStream,fieldName, fileName)
        // const streamToBuffer = stream => {
        //     return new Promise((resolve, reject) => {
        //       const buffers = [];
        //       stream.on('error', reject);
        //       stream.on('data', data => buffers.push(data));
        //       stream.on('end', () => resolve(Buffer.concat(buffers)));
        //     });
        //   };
        //   const buf = await streamToBuffer(fileStream);
        //   console.log('235**********', buf);
          
        // writeStream.write(buf, 'utf-8', () => {
        //     console.log('226************');
            
        // })
        
    }
    /**
     * {des} delete user
     */
    async user_delete() {
        const query = this.ctx.request.body,
            uid = query.id;
        const res = await this.ctx.service.member.member_delete(uid);
        if(res) {
            this.ctx.status = 200;
            return this.ctx.body = {
                s: 1,
                m: 'ok',
                d: {}
            }
        }else {
            this.ctx.status = 500;
            return this.ctx.body = {
                s: 0,
                m: 'fail~',
                d: {}
            }
        }
    }
}

module.exports = MemberController;